// ==UserScript==
// @name            从豆包下载无水印图片 Download Origin Image from Doubao without Watermark
// @name:en         Download Origin Image from Doubao without Watermark 从豆包下载无水印图片
// @namespace       https://github.com/catscarlet/Download-Origin-Image-from-Doubao-without-Watermark
// @description     从豆包（www.doubao.com）下载无水印图片 Download Origin Image from www.doubao.com without Watermark.
// @description:en  Download Origin Image from www.doubao.com without Watermark. 从豆包（www.doubao.com）下载无水印图片
// @version         0.6.2
// @author          catscarlet
// @license         GNU Affero General Public License v3.0
// @match           https://www.doubao.com/chat/*
// @run-at          document-end
// @grant           GM_download
// @grant           unsafeWindow
// ==/UserScript==

const removeDefaultDownloadButton = 1; // 隐藏原下载按钮。若要显示，设为0

(function() {
    'use strict';

    // 配置项
    const config = {
        buttonText: '点击下载无水印图片',
        buttonClasses: 'imagelink-nowatermark semi-button semi-button-primary samantha-button-DHlMIF tertiary-txLFty small-F5C1jo icon-EzBhnh button-N4Cski small-YnXoGL semi-button-with-icon',
        loadingClasses: 'bg-gray-500 cursor-not-allowed',
        errorClasses: 'bg-red-500',
        throttleDelay: 300,
        debounceDelay: 300
    };

    let throttleTimer = null;
    let debounceTimer = null;

    // 获取图片原始URL（尝试从data-original-src属性获取）
    const getOriginalImageUrl = (imgElement) => {
        return imgElement.getAttribute('data-original-src') || imgElement.src;
    };

    // 格式化日期时间
    const getFormattedDateTime = () => {
        const now = new Date();
        return now.toISOString().replace(/[:-]/g, '').replace('T', '').split('.')[0];
    };

    // 获取图片名称
    const getImageName = (imgElement) => {
        try {
            const title = document.title.replace('- 豆包', '').trim() || '豆包图片';
            const chatId = document.location.pathname.replace('/chat/', '').trim() || 'unknown';
            const timeStr = getFormattedDateTime();
            const altText = imgElement.alt || 'image';
            const cleanAlt = altText.replace(/[^\w\s-]/g, '').trim().replace(/\s+/g, '-');

            return `${title}-${chatId}-${timeStr}-${cleanAlt}.png`;
        } catch (e) {
            console.warn('生成图片名称失败:', e);
            return `doubao-image-${getFormattedDateTime()}.png`;
        }
    };

    // 下载图片
    const downloadImage = async (imgUrl, fileName, linkElement) => {
        try {
            // 显示下载中状态
            const originalText = linkElement.textContent;
            const originalClasses = linkElement.className;

            linkElement.textContent = '下载中...';
            linkElement.className = `${originalClasses} ${config.loadingClasses}`;

            // 尝试使用GM_download
            if (typeof GM_download !== 'undefined') {
                return new Promise((resolve, reject) => {
                    GM_download({
                        url: imgUrl,
                        name: fileName,
                        saveAs: false,
                        onerror: (error) => {
                            console.error('GM_download 失败:', error);
                            linkElement.textContent = '下载失败，重试';
                            linkElement.className = `${originalClasses} ${config.errorClasses}`;

                            // 3秒后恢复按钮状态
                            setTimeout(() => {
                                linkElement.textContent = originalText;
                                linkElement.className = originalClasses;
                            }, 3000);

                            reject(error);
                        },
                        onload: () => {
                            // 下载成功，恢复按钮状态
                            linkElement.textContent = originalText;
                            linkElement.className = originalClasses;
                            resolve();
                        }
                    });
                });
            }

            // 备用方法：使用fetch
            const response = await fetch(imgUrl, { mode: 'cors' });
            if (!response.ok) {
                throw new Error(`HTTP错误，状态码: ${response.status}`);
            }

            const blob = await response.blob();
            const url = URL.createObjectURL(blob);

            const a = document.createElement('a');
            a.href = url;
            a.download = fileName;
            document.body.appendChild(a);

            // 使用requestAnimationFrame优化点击
            requestAnimationFrame(() => {
                a.click();
                requestAnimationFrame(() => {
                    setTimeout(() => {
                        URL.revokeObjectURL(url);
                        document.body.removeChild(a);
                        linkElement.textContent = originalText;
                        linkElement.className = originalClasses;
                    }, 1000);
                });
            });

        } catch (error) {
            console.error('图片下载失败:', error);
            alert(`图片下载失败: ${error.message}`);
            linkElement.textContent = '下载失败，重试';
            linkElement.className = `${config.buttonClasses} ${config.errorClasses}`;

            // 恢复按钮状态
            setTimeout(() => {
                linkElement.textContent = config.buttonText;
                linkElement.className = config.buttonClasses;
            }, 3000);
        }
    };

    // 添加下载按钮
    const addDownloadButton = (imgElement) => {
        if (!imgElement || imgElement.closest('.imagelink-container')) return;

        const parent = imgElement.parentElement;
        if (!parent) return;

        // 检查是否已添加按钮
        if (parent.querySelector('.imagelink-nowatermark')) return;

        // 创建容器以定位按钮
        const container = document.createElement('div');
        container.className = 'imagelink-container relative inline-block';

        // 将图片移入容器
        parent.replaceChild(container, imgElement);
        container.appendChild(imgElement);

        // 创建下载按钮
        const link = document.createElement('a');
        link.textContent = config.buttonText;
        link.className = `imagelink-nowatermark ${config.buttonClasses}`;

        // 定位按钮到左上角
        link.classList.add('absolute', 'left-2', 'top-1/2', '-translate-y-1/2', 'z-10');

        // 绑定点击事件
        link.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();

            const imgUrl = getOriginalImageUrl(imgElement);
            const fileName = getImageName(imgElement);

            downloadImage(imgUrl, fileName, link);
        });

        container.appendChild(link);
    };

    // 处理DOM变化
    const handleMutations = (mutationsList) => {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList') {
                // 隐藏原始下载按钮
                if (removeDefaultDownloadButton) {
                    document.querySelectorAll('div[data-testid="edit_image_download_button"]').forEach(btn => {
                        btn.style.display = 'none';
                    });
                }

                // 查找并处理图片
                document.querySelectorAll('img.preview-img-uz4sQR.img-bg-kZaLvT').forEach(img => {
                    addDownloadButton(img);
                });
            }
        }
    };

    // 创建节流函数
    const throttle = (callback, delay) => {
        return function(...args) {
            if (!throttleTimer) {
                throttleTimer = setTimeout(() => {
                    callback(...args);
                    throttleTimer = null;
                }, delay);
            }
        };
    };

    // 创建防抖函数
    const debounce = (callback, delay) => {
        return function(...args) {
            clearTimeout(debounceTimer);
            debounceTimer = setTimeout(() => {
                callback(...args);
            }, delay);
        };
    };

    // 初始化
    const init = () => {
        try {
            // 立即处理现有图片
            handleMutations([{ type: 'childList' }]);

            // 设置观察者
            const observer = new MutationObserver(throttle(debounce(handleMutations, config.debounceDelay), config.throttleDelay));
            observer.observe(document.documentElement, {
                childList: true,
                subtree: true
            });

            console.log('豆包无水印图片下载脚本已加载');
        } catch (error) {
            console.error('脚本初始化失败:', error);
        }
    };

    // 当DOM加载完成后初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();